#include "ui_germtab.h"
#include "germtab.h"

GermTab::GermTab(QWidget *parent) :
    QWidget(parent), ui(new Ui::GermTab), imgL(0),
    tcon(new TrainingControl), total(0),
    percent(50), approach(1), size(500), step(100),
    max(1500), hiddenN(10)
{
    ui->setupUi(this);
	// Type of method for retrieving data
    ui->appBox->addItem("STATIC");
    ui->appBox->addItem("GROWING");
    ui->appBox->addItem("WINDOWING");

    // Connect each button to a corresponding event listener
    connect(ui->percentSlider, SIGNAL(sliderMoved(int)), this, SLOT(showPercent(int)));
    connect(ui->appBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setApproach(int)));
    connect(ui->sizeEdit, SIGNAL(textEdited(QString)), this, SLOT(setSize(QString)));
    connect(ui->stepEdit, SIGNAL(textEdited(QString)), this, SLOT(setStep(QString)));
    connect(ui->maxEdit, SIGNAL(textEdited(QString)), this, SLOT(setMaxEpochs(QString)));
    connect(ui->hiddenEdit, SIGNAL(textEdited(QString)), this, SLOT(setHiddenN(QString)));
    connect(ui->loadButton, SIGNAL(clicked()), this, SLOT(load()));
    connect(ui->waveletBox, SIGNAL(toggled(bool)), this, SLOT(setWavelet(bool)));
    connect(ui->trainNNButton, SIGNAL(clicked()), this, SLOT(trainNN()));
    connect(ui->runNNButton, SIGNAL(clicked()), this, SLOT(runNN()));
    connect(ui->weightsButton, SIGNAL(clicked()), this, SLOT(loadWeights()));
    connect(ui->runSVMButton, SIGNAL(clicked()), this, SLOT(runSVM()));
    connect(ui->runMLPButton, SIGNAL(clicked()), this, SLOT(runMLP()));
    connect(ui->runBoostButton, SIGNAL(clicked()), this, SLOT(runBoost()));

    // Wavelet box is checked by default
    ui->waveletBox->setChecked(true);
}

GermTab::~GermTab()
{
    delete ui;
}

void GermTab::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

/*
 *	Indicates whether to perform wavelet transform for image
 */
void GermTab::setWavelet(bool checked)
{
    tcon->getGTools()->setWavelet(checked);
    // Wavelet box is disabled
    ui->waveletBox->setEnabled(false);
}

/*
 *	When method is 'Growing', a fixed percentage will
 *	be set and data set will increase with this percentage
 *	every epoch
 */
void GermTab::showPercent(int percent)
{
    this->percent = percent;
    ui->perLabel->setText(QString::number(percent).append(tr("%")));
}

/*
 *	A total of three method to retrieve data set
 *	'Static', 'Growing', 'Windowing'. Default will
 *	be 'static' method
 */
void GermTab::setApproach(int approach)
{
	// approach is 0-based, need to plus one
    this->approach = approach + 1;
	// Depending on selected approach, enable corresponding GUI components
    if(approach == 1)
    {
        ui->splitter_5->setEnabled(true);
        ui->splitter_7->setEnabled(false);
    }
    else if(approach == 2)
    {
        ui->splitter_5->setEnabled(false);
        ui->splitter_7->setEnabled(true);
    }
}

/*
 *	Size of windowing method. If no selection
 *	default will be 500
 */
void GermTab::setSize(QString input)
{
	// Get integer value from input of type qstring
    size = toInt(input);
	// If size is 0 and invalid input, set size to 500 by default
    if(size == 0)
    {
        size = 500;
        ui->sizeEdit->setStatusTip("size will be 500 by default");
    }
}

/*
 *	Size of step every time window moves. If no
 *	selection, default will be 100
 */
void GermTab::setStep(QString input)
{
	// Get input value of integer type
    step = toInt(input);
	// If input value is not valid or 0, set it to 10 by default
    if(step == 0)
    {
        step = 10;
        ui->stepEdit->setStatusTip("step will be 10 by default");
    }
}

/*
 *	Max number of epochs before neural network stops.
 *	Default value will be 1500 epochs
 */
void GermTab::setMaxEpochs(QString input)
{
	// Get integer type of input for max number of epochs
    max = toInt(input);
	// Set max to 1500 if input is 0 or invalid
    if(max == 0)
    {
        max = 1500;
        ui->maxEdit->setStatusTip("max epochs will be 1500 by default");
    }
}

/*
 *	Number of hidden neurons. Default value
 *	will be 10 hidden neurons
 */
void GermTab::setHiddenN(QString input)
{
	// Get integer type of input
    hiddenN = toInt(input);
	// Set to default value if zero or invalid
    if(hiddenN == 0)
    {
        hiddenN = 10;
        ui->hiddenEdit->setStatusTip("number of hidden neurons will be 10 by default");
    }
}

/*
 *	Convert user input to integer value
 *	from string input
 */
int GermTab::toInt(const QString &input)
{
    bool ok;
    return input.toInt(&ok, 10);
}

/*
 *  TrainNN button is pressed and start training neural network
 *  A training file needs to be provided plus a list of parameters
 *	which have been entered or default value 
 */
void GermTab::trainNN()
{
	// Open training file
    QString trFile = QFileDialog::getOpenFileName(this, tr("Open training file for Neural Network"), "/home",
                                                    tr("Training file (*.csv)"));

    // Call training control to start training neural netowrk
    if(tcon->getGTools()->startTraining(trFile, approach, percent, size, step, max, hiddenN))
    {
        ui->trainNNButton->setStatusTip("Neural Network has been trained successfully!");
        ui->runNNButton->setEnabled(true);
    }
    else
    {
        ui->trainNNButton->setStatusTip("No training file available, please train Neural Network first!");
        ui->runNNButton->setEnabled(false);
    }
}

/*
 *	This method loades a file of previously trained neural network weights. Once loaded, neural network
 *	is ready to run on target image to detect germination
 *
 */
void GermTab::loadWeights()
{
	// Open a file where weights are saved
    QString wtFile = QFileDialog::getOpenFileName(this, tr("Open weight file for Neural Network"), "/home",
                                                    tr("Weight file (*.csv)"));
	// Initialized neural network with weights for both hidden layer and output layer, plus
	// number of hidden neurons and output neurons
    if(tcon->getGTools()->loadWeights(wtFile, hiddenN))
    {
        ui->weightsButton->setStatusTip("Weights have load successfully");
        ui->runNNButton->setEnabled(true);
    }
    else
    {
        ui->weightsButton->setStatusTip("No weights available, or Incorrect number of weights in input file!");
        ui->runNNButton->setEnabled(false);
    }
}

/*
 *  Run button is pressed
 *  Set program to running mode and load any image to be
 *  identified with trained neural network.
 */
void GermTab::runNN()
{
    // Once an image has been loaded in training control
    // run NN to test it.
    tcon->startNN();
    // current image in image loader is the image need
    // to be tested by neural network
    loadTCon();
}

void GermTab::runSVM()
{
    // Once an image has been loaded in training control
    // run NN to test it.
    tcon->startSVM();
    // current image in image loader is the image need
    // to be tested by neural network
    loadTCon();
}

void GermTab::runMLP()
{
    // Once an image has been loaded in training control
    // run NN to test it.
    tcon->startMLP();
    // current image in image loader is the image need
    // to be tested by neural network
    loadTCon();
}

void GermTab::runBoost()
{
    // Once an image has been loaded in training control
    // run NN to test it.
    tcon->startBoost();
    // current image in image loader is the image need
    // to be tested by neural network
    loadTCon();
}

void GermTab::svmReady(Classifier *classifier)
{
    tcon->getGTools()->addClassifier(classifier);
    ui->runSVMButton->setEnabled(true);
}

void GermTab::mlpReady(Classifier *classifier)
{
    tcon->getGTools()->addClassifier(classifier);
    ui->runMLPButton->setEnabled(true);
}

void GermTab::boostReady(Classifier *classifier)
{
    tcon->getGTools()->addClassifier(classifier);
    ui->runBoostButton->setEnabled(true);
}

/*
 *	Load image into 'training control' and start calculating seed texture
 *	features based on coccurance
 */
void GermTab::load()
{
    if(loadTCon())
    {
        // update number of trained image
        ui->nTrainedImg->setText(QString::number(++total));

        if(!ui->trainNNButton->isEnabled())
            ui->trainNNButton->setEnabled(true);
    }
}

/*
 *  Load up training control, display current image from
 *  image loader.
 *
 */
bool GermTab::loadTCon()
{
    if(imgL)
    {
		// Get current displayed image on the left side of image loader
        QString file = imgL->getCurrFile();

        if(file.length() > 0)
        {
            tcon->addFile(file);
            tcon->show();
            return true;
        }
        else
        {
            this->setStatusTip("Please select an image first.");
        }
    }
    else
    {
        QMessageBox msgBox;
        msgBox.setText("No images have been loaded.");
        msgBox.exec();
    }
    return false;
}

/*
 *	Add image loader to current germ tab
 *
 */
void GermTab::addLoader(ImageLoader *imageLoader)
{    
    if(imageLoader)
    {
        ui->gridLayout->addWidget(imageLoader, 0, 0);
        imgL = imageLoader;
    }
}

void GermTab::showContent()
{
    if(imgL)
        ui->gridLayout->addWidget(imgL, 0, 0);
}
